home *** CD-ROM | disk | FTP | other *** search
- #define NAME "StripHunks"
- #define REVISION "8"
-
- /* Programmheader
-
- Name: StripHunks
- Author: SDI
- Distribution: PD
- Description: removes debug, symbol and name hunks
- Compileropts: -
- Linkeropts: -gsi -l amiga
-
- 1.0 08.02.98 : first version
- 1.1 12.02.98 : compiled with SAS
- 1.2 10.03.98 : fixed SAS local base system
- 1.3 03.06.98 : fixed Enforcer hit
- 1.4 18.08.98 : wrote own strip routines and removed xfd use
- 1.5 04.12.98 : added lots of new options
- 1.6 12.12.98 : added sorting for short relocs
- 1.7 08.02.99 : fixed NOSTRIP options
- 1.8 09.10.99 : added SORTBACKWARDS
- */
-
- #include <proto/dos.h>
- #include <proto/exec.h>
- #include <exec/memory.h>
- #include <dos/doshunks.h>
- #include "SDI_defines.h"
-
- #define PARAM "FILES/M,ONLYSHOW/S,ALL/S,SORT=SORTRELOC/S," \
- "NOSTRIP/S,NSE=NOSTRIPEMPTY/S,NSN=NOSTRIPNAME/S,"\
- "NSD=NOSTRIPDEBUG/S,NSS=NOSTRIPSYMBOL/S," \
- "NSR=NOSTRIPRELOC/S,SBW=SORTBACKWARDS/S"
- #define PATHSIZE 256
-
- struct Args {
- STRPTR *files;
- ULONG onlyshow;
- ULONG all;
- ULONG sortreloc;
- ULONG nostrip;
- ULONG nostripempty;
- ULONG nostripname;
- ULONG nostripdebug;
- ULONG nostripsymbol;
- ULONG nostripreloc;
- ULONG sortbackwards;
- };
-
- struct ExecBase *SysBase = 0;
-
- #ifdef __SASC
- #define DOSBase dosbase
- #define ASSIGN_DOS
- #else
- struct DosLibrary * DOSBase = 0;
- #define ASSIGN_DOS DOSBase = dosbase;
- #endif
-
- #define STRIPFLAG_SORTRELOC (1<<0)
- #define STRIPFLAG_NOSTRIPEMPTY (1<<1)
- #define STRIPFLAG_NOSTRIPNAME (1<<2)
- #define STRIPFLAG_NOSTRIPDEBUG (1<<3)
- #define STRIPFLAG_NOSTRIPSYMBOL (1<<4)
- #define STRIPFLAG_NOSTRIPRELOC (1<<5)
-
- #define STRIPFLAG_SORTBACKWARDS (1<<8)
-
- #define STRIPFLAG_SORTFAILED (1<<10)
- #define STRIPFLAG_EMPTY (1<<11)
- #define STRIPFLAG_NAME (1<<12)
- #define STRIPFLAG_DEBUG (1<<13)
- #define STRIPFLAG_SYMBOL (1<<14)
- #define STRIPFLAG_RELOC (1<<15)
- #define STRIPFLAG_RELOCSORT (1<<16)
-
- #define STRIPFLAG_SORTED (1<<20)
- #define STRIPFLAG_STRIPPEDDEBUG (1<<21)
- #define STRIPFLAG_STRIPPEDEMPTY (1<<22)
- #define STRIPFLAG_STRIPPEDNAME (1<<23)
- #define STRIPFLAG_STRIPPEDSYMBOL (1<<24)
- #define STRIPFLAG_STRIPPEDRELOC (1<<25)
-
- LONG StripHunks(ULONG *buf, ULONG *rl, ULONG l, ULONG *resflag, ULONG flags);
- ULONG DoSort(ULONG *buf, ULONG *resflags, ULONG flags);
- ULONG DoSortShort(UWORD *buf, ULONG *resflags, ULONG flags);
- LONG SortList(struct RelocData *rd, ULONG size, ULONG flags);
- void DoCopy(ULONG *buf, ULONG j, ULONG skip, ULONG size);
-
- struct RelocData {
- UWORD num;
- UWORD hunk;
- ULONG data;
- };
-
- ULONG start(void)
- {
- ULONG ret = RETURN_FAIL;
- struct DosLibrary *dosbase;
-
- SysBase = (*((struct ExecBase **) 4));
- { /* test for WB and reply startup-message */
- struct Process *task;
- if(!(task = (struct Process *) FindTask(0))->pr_CLI)
- {
- WaitPort(&task->pr_MsgPort);
- Forbid();
- ReplyMsg(GetMsg(&task->pr_MsgPort));
- return RETURN_FAIL;
- }
- }
-
- if((dosbase = (struct DosLibrary *) OpenLibrary("dos.library", 37)))
- {
- STRPTR none = 0;
- struct Args args;
- struct RDArgs *rda;
-
- ASSIGN_DOS
- args.files = 0;
- args.onlyshow = args.all = args.sortreloc = args.nostripname =
- args.nostripempty = args.nostripdebug = args.nostripsymbol =
- args.nostrip = args.nostripreloc = args.sortbackwards = 0;
-
- if((rda = ReadArgs(PARAM, (LONG *) &args, 0)))
- {
- struct AnchorPath *APath;
- ULONG flags = 0;
-
- if(args.sortbackwards) flags |= STRIPFLAG_SORTBACKWARDS;
- if(args.sortreloc) flags |= STRIPFLAG_SORTRELOC;
- if(args.nostripname) flags |= STRIPFLAG_NOSTRIPNAME;
- if(args.nostripempty) flags |= STRIPFLAG_NOSTRIPEMPTY;
- if(args.nostripdebug) flags |= STRIPFLAG_NOSTRIPDEBUG;
- if(args.nostripsymbol) flags |= STRIPFLAG_NOSTRIPSYMBOL;
- if(args.nostripreloc) flags |= STRIPFLAG_NOSTRIPRELOC;
- if(args.nostrip) flags |= STRIPFLAG_NOSTRIPEMPTY|
- STRIPFLAG_NOSTRIPNAME|STRIPFLAG_NOSTRIPDEBUG|
- STRIPFLAG_NOSTRIPSYMBOL|STRIPFLAG_NOSTRIPRELOC;
-
- /* args.files is cleared, when no arguments passed -- OS bug? */
- if(!args.files)
- args.files = &none;
-
- if((APath = (struct AnchorPath *) AllocMem(sizeof(struct AnchorPath)+
- PATHSIZE, MEMF_PUBLIC|MEMF_CLEAR)))
- {
- ULONG retval = ERROR_NO_MORE_ENTRIES;
-
- APath->ap_BreakBits = SIGBREAKF_CTRL_C;
- APath->ap_Strlen = PATHSIZE;
-
- while(*args.files && retval == ERROR_NO_MORE_ENTRIES)
- {
- for(retval = MatchFirst(*args.files, APath); !retval;
- retval = MatchNext(APath))
- {
- if(APath->ap_Flags & APF_DIDDIR)
- APath->ap_Flags &= ~APF_DIDDIR;
- else if(APath->ap_Info.fib_DirEntryType > 0)
- {
- if(args.all)
- APath->ap_Flags |= APF_DODIR;
- }
- else
- {
- BPTR fh;
- LONG err = 0;
-
- if((fh = Open(APath->ap_Buf, MODE_OLDFILE)))
- {
- struct FileInfoBlock *fib;
-
- if((fib = (struct FileInfoBlock *) AllocDosObject(DOS_FIB, 0)))
- {
- if(ExamineFH(fh, fib))
- {
- ULONG length;
-
- if((length = fib->fib_Size) > 4)
- {
- ULONG reslength;
-
- if(Read(fh, &reslength, 4) == 4)
- {
- if(reslength == HUNK_HEADER)
- {
- ULONG *buf;
-
- if((buf = (ULONG *) AllocMem(length+3, MEMF_ANY|MEMF_CLEAR)))
- {
- if(Read(fh, buf+1, length-4) == length-4)
- {
- ULONG resflags = 0;
- *buf = reslength; /* store HUNK ID */
-
- if((err = StripHunks(buf, &reslength, length, &resflags, flags)) > 0)
- {
- if(reslength < length || (resflags & STRIPFLAG_SORTED))
- {
- Printf("File '%s': ", APath->ap_Buf);
- if(resflags & STRIPFLAG_STRIPPEDNAME)
- Printf("NAME, ");
- if(resflags & STRIPFLAG_STRIPPEDDEBUG)
- Printf("DEBUG, ");
- if(resflags & STRIPFLAG_STRIPPEDSYMBOL)
- Printf("SYMBOL, ");
- if(resflags & STRIPFLAG_STRIPPEDRELOC)
- Printf("RELOC, ");
- if(resflags & STRIPFLAG_STRIPPEDEMPTY)
- Printf("EMPTY ");
- if(length-reslength)
- Printf("total %ld bytes stripped", length-reslength);
- if(resflags & STRIPFLAG_SORTED)
- Printf("%sRELOC sorted", length-reslength ? ", " : "");
- Printf("\n");
- if(!args.onlyshow)
- {
- if(ChangeMode(CHANGE_FH,fh,EXCLUSIVE_LOCK))
- {
- if(!SetFileSize(fh,0,OFFSET_BEGINNING))
- {
- if(Write(fh, buf, reslength) != reslength)
- Printf("Write error on file '%s'\n", APath->ap_Buf);
- }
- else
- err = 0;
- }
- else
- err = 0;
- }
- }
- }
- if(err < 0 || (resflags&(STRIPFLAG_EMPTY|STRIPFLAG_NAME|
- STRIPFLAG_DEBUG|STRIPFLAG_SYMBOL|STRIPFLAG_RELOC|
- STRIPFLAG_SORTFAILED|STRIPFLAG_RELOCSORT)))
- {
- Printf("File '%s': ", APath->ap_Buf);
- if(err == -2)
- {
- Printf("Unknown hunk type");
- err = 1;
- }
- else if(err == -1)
- {
- Printf("Strange hunk structure or overlay");
- err = 1;
- } /* else StripHunks */
- else
- {
- if(resflags & STRIPFLAG_EMPTY)
- Printf("EMPTY, ");
- if(resflags & STRIPFLAG_NAME)
- Printf("NAME, ");
- if(resflags & STRIPFLAG_DEBUG)
- Printf("DEBUG, ");
- if(resflags & STRIPFLAG_SYMBOL)
- Printf("SYMBOL, ");
- if(resflags & (STRIPFLAG_RELOC|STRIPFLAG_RELOCSORT))
- Printf("RELOC, ");
- if(resflags & STRIPFLAG_SORTFAILED)
- Printf("UNSORTED, ");
- Printf("still exists");
- }
- Printf("\n");
- }
- } /* Read */
- FreeMem(buf, length+3);
- } /* AllocMem */
- } /* HUNK_HEADER ? */
- else
- err = 1;
- } /* Read 4 */
- } /* size > 4 */
- else
- err = 1;
- } /* Examine */
- FreeDosObject(DOS_FIB,fib);
- } /* AlloDosObject */
- if(fh)
- Close(fh);
- }
- if(err < 0)
- Printf("Error on file '%s'\n", APath->ap_Buf);
- }
- }
- MatchEnd(APath);
- ++args.files;
- }
- if(retval == ERROR_NO_MORE_ENTRIES)
- ret = 0;
-
- FreeMem(APath, sizeof(struct AnchorPath)+PATHSIZE);
- }
- FreeArgs(rda);
- }
- if(ret)
- PrintFault(IoErr(), 0);
-
- CloseLibrary((struct Library *) dosbase);
- }
- return ret;
- }
-
- LONG StripHunks(ULONG *buf, ULONG *rl, ULONG l, ULONG *resflags, ULONG flags)
- {
- LONG i, j, empty = 0, skipend = 0, ret = 1;
- /* skipend -- should last empty hunk be skipped */
-
- if(l & 3 || buf[1] || buf[2] != buf[4]+1 || buf[3])
- return -1;
-
- l >>= 2;
- i = buf[2];
-
- for(j = 0; j < i; ++j) /* empty hunks */
- {
- if(!buf[5+j])
- ++empty;
- }
-
- if(empty)
- {
- if(buf[4+j] || empty > 1 || (flags & STRIPFLAG_NOSTRIPEMPTY))
- {
- *resflags |= STRIPFLAG_EMPTY; empty = 0;
- }
- else /* skip empty hunks at file end */
- {
- *resflags |= STRIPFLAG_STRIPPEDEMPTY;
- DoCopy(buf, 4+(i--), 1, l--);
- --buf[2];
- --buf[4];
- }
- }
-
- j = (5+i);
- while(j < l)
- {
- if(buf[j] == HUNK_DEBUG)
- {
- i = 2+buf[j+1];
- if(flags & STRIPFLAG_NOSTRIPDEBUG)
- {
- j += i; *resflags |= STRIPFLAG_DEBUG;
- }
- else
- {
- *resflags |= STRIPFLAG_STRIPPEDDEBUG;
- DoCopy(buf, j, i, l);
- l -= i;
- }
- }
- else if(buf[j] == HUNK_NAME)
- {
- i = 2+buf[j+1];
- if(flags & STRIPFLAG_NOSTRIPNAME)
- {
- j += i; *resflags |= STRIPFLAG_NAME;
- }
- else
- {
- *resflags |= STRIPFLAG_STRIPPEDNAME;
- DoCopy(buf, j, i, l);
- l -= i;
- }
- }
- else if(buf[j] == HUNK_SYMBOL)
- {
- i = j+1;
- while(buf[i])
- i += buf[i]+2;
- i = i-j+1;
- if(flags & STRIPFLAG_NOSTRIPSYMBOL)
- {
- j += i; *resflags |= STRIPFLAG_SYMBOL;
- }
- else
- {
- *resflags |= STRIPFLAG_STRIPPEDSYMBOL;
- DoCopy(buf, j, i, l);
- l -= i;
- }
- }
- else if((buf[j]&0xFFFFFF) == HUNK_CODE || (buf[j]&0xFFFFFF) == HUNK_DATA)
- {
- if(empty && !buf[j+1])
- {
- *resflags |= STRIPFLAG_STRIPPEDEMPTY;
- DoCopy(buf, j, 2, l);
- l -= 2;
- skipend = 1;
- }
- else
- j += 2+buf[j+1];
- }
- else if((buf[j]&0xFFFFFF) == HUNK_BSS)
- {
- if(empty && !buf[j+1])
- {
- *resflags |= STRIPFLAG_STRIPPEDEMPTY;
- DoCopy(buf, j, 2, l);
- l -= 2;
- skipend = 1;
- }
- else
- j += 2;
- }
- else if(buf[j] == HUNK_END)
- {
- if(skipend)
- {
- DoCopy(buf, j, 1, l--);
- skipend = 0;
- }
- else
- ++j;
- }
- else if(buf[j] == HUNK_RELOC32)
- {
- if(!buf[j+1]) /* empty reloc */
- {
- if(flags & STRIPFLAG_NOSTRIPRELOC)
- {
- j += 2; *resflags |= STRIPFLAG_RELOC;
- }
- else
- {
- *resflags |= STRIPFLAG_STRIPPEDRELOC;
- DoCopy(buf, j, 2, l);
- l -= 2;
- }
- }
- else
- {
- ++j;
- i = DoSort(buf + j, resflags, flags);
- while(buf[j])
- {
- j += 2+buf[j];
- }
- ++j;
- if(i)
- {
- *resflags |= STRIPFLAG_STRIPPEDRELOC;
- DoCopy(buf, j, i, l);
- l -= i;
- }
- if(skipend)
- return -1;
- }
- }
- else if(buf[j] == HUNK_DREL32 || buf[j] == HUNK_RELOC32SHORT)
- {
- UWORD *b;
-
- b = (UWORD *) (buf+j+1);
-
- if(*b == 0) /* empty reloc */
- {
- if(flags & STRIPFLAG_NOSTRIPRELOC)
- {
- j += 2; *resflags |= STRIPFLAG_RELOC;
- }
- else
- {
- *resflags |= STRIPFLAG_STRIPPEDRELOC;
- DoCopy(buf, j, 2, l);
- l -= 2;
- }
- }
- else
- {
- i = DoSortShort(b, resflags, flags);
- while(*b)
- {
- b += 2+(*b);
- }
- j = (((STRPTR) (b+2)) - ((STRPTR) buf))>>2;
- if(i)
- {
- *resflags |= STRIPFLAG_STRIPPEDRELOC;
- DoCopy(buf, j, i>>1, l);
- l -= i;
- }
- if(skipend)
- return -1;
- }
- }
- else
- return -2;
- }
-
- *rl = l<<2;
- return ret;
- }
-
- ULONG DoSort(ULONG *buf, ULONG *resflags, ULONG flags)
- {
- ULONG num, size;
- ULONG k, i, j, l;
- struct RelocData *rd;
-
- if(!(flags & STRIPFLAG_SORTRELOC))
- return 0;
-
- k = num = 0;
- while(buf[k])
- {
- num += buf[k];
- k += 2+buf[k];
- }
-
- if(!(rd = (struct RelocData *) AllocMem(sizeof(struct RelocData)*num,MEMF_ANY)))
- {
- *resflags |= STRIPFLAG_SORTFAILED; return 0;
- }
-
- k = j = l = 0;
- while(buf[k])
- {
- for(i = 0; i < buf[k]; ++i)
- {
- rd[j].hunk = buf[k+1];
- rd[j].num = (flags & STRIPFLAG_NOSTRIPRELOC) ? buf[k+1]*256+l : buf[k+1];
- rd[j++].data = buf[k+2+i];
- }
- k += 2+buf[k];
- ++l;
- }
-
- size = ++k;
- if(SortList(rd, num, flags))
- *resflags |= STRIPFLAG_SORTED;
- for(l = k = 0; l < num;)
- {
- for(j = 0; rd[l+j].num == rd[l].num && l+j<num; ++j)
- ;
- if(rd[l].hunk == rd[l+j].hunk)
- *resflags |= STRIPFLAG_RELOCSORT;
- buf[k++] = j;
- buf[k++] = rd[l].hunk;
- while(j--)
- buf[k++] = rd[l++].data;
- }
- buf[k++] = 0;
-
- FreeMem(rd, sizeof(struct RelocData)*num);
-
- return size-k;
- }
-
- ULONG DoSortShort(UWORD *buf, ULONG *resflags, ULONG flags)
- {
- ULONG num, size;
- ULONG k, i, j, l;
- struct RelocData *rd;
-
- if(!(flags & STRIPFLAG_SORTRELOC))
- return 0;
-
- k = num = 0;
- while(buf[k])
- {
- num += buf[k];
- k += 2+buf[k];
- }
-
- if(!(rd = (struct RelocData *) AllocMem(sizeof(struct RelocData)*num,MEMF_ANY)))
- {
- *resflags |= STRIPFLAG_SORTFAILED; return 0;
- }
-
- k = j = l = 0;
- while(buf[k])
- {
- for(i = 0; i < buf[k]; ++i)
- {
- rd[j].hunk = buf[k+1];
- rd[j].num = (flags & STRIPFLAG_NOSTRIPRELOC) ? buf[k+1]*256+l : buf[k+1];
- rd[j++].data = buf[k+2+i];
- }
- k += 2+buf[k];
- ++l;
- }
-
- if((size = ++k) & 1)
- ++size;
- if(SortList(rd, num, flags))
- *resflags |= STRIPFLAG_SORTED;
- for(l = k = 0; l < num;)
- {
- for(j = 0; rd[l+j].num == rd[l].num && l+j<num; ++j)
- ;
- if(rd[l].hunk == rd[l+j].hunk)
- *resflags |= STRIPFLAG_RELOCSORT;
- buf[k++] = j;
- buf[k++] = rd[l].hunk;
- while(j--)
- buf[k++] = rd[l++].data;
- }
- buf[k++] = 0;
- if(k & 1)
- buf[k++] = 0;
-
- FreeMem(rd, sizeof(struct RelocData)*num);
-
- return size-k;
- }
-
- LONG SortList(struct RelocData *rd, ULONG size, ULONG flags)
- {
- ULONG i, j, k;
- LONG res = 0;
- struct RelocData s;
-
- if(flags & STRIPFLAG_SORTBACKWARDS)
- {
- for(i = 0; i < size; ++i)
- {
- for(j = k = i; j < size; ++j)
- {
- if(rd[j].num < rd[k].num || (rd[j].num == rd[k].num && rd[j].data > rd[k].data))
- k = j;
- }
- if(k != i)
- {
- s = rd[i];
- rd[i] = rd[k];
- rd[k] = s;
- res = 1;
- }
- }
- }
- else
- {
- for(i = 0; i < size; ++i)
- {
- for(j = k = i; j < size; ++j)
- {
- if(rd[j].num < rd[k].num || (rd[j].num == rd[k].num && rd[j].data < rd[k].data))
- k = j;
- }
- if(k != i)
- {
- s = rd[i];
- rd[i] = rd[k];
- rd[k] = s;
- res = 1;
- }
- }
- }
- return res;
- }
-
- void DoCopy(ULONG *buf, ULONG j, ULONG skip, ULONG size)
- {
- ULONG i;
-
- buf += j;
- size -= j;
-
- for(i = 0; i < size; ++i)
- {
- buf[i] = buf[i+skip];
- }
- }
-